#include <stdio.h>
#include <stdlib.h>


//#define _DEBUG_LOG

#include "../include/log.h"

struct list_node {
	int data;
	struct list_node *next;
};

struct list_node *create_list()
{
	DEBUG_LOG("start");
	struct list_node *list_node = (struct list_node *)malloc(sizeof(struct list_node));
	list_node->data = 0;
	list_node->next = NULL;
	DEBUG_LOG("end list_node = %p", list_node);
	return list_node;
}

struct list_node *create_node(int data)
{
	DEBUG_LOG("start data = %d", data);
	struct list_node *new_node = (struct list_node *)malloc(sizeof(struct list_node));
	new_node->data = data;
	new_node->next = NULL;
	DEBUG_LOG("end new_node = %p", new_node);
	return new_node;
}

int get_list_length(struct list_node *head)
{
	DEBUG_LOG("start head = %p", head);
	if(!head) {
		ERROR_LOG("head = NULL");
		return -1;
	}
	int length = 0;
	struct list_node *node = head->next;
	while(node) {
		length++;
		node = node->next;
	}
	DEBUG_LOG("end length = %d", length);
	return length;
}

int insert_head(struct list_node *head, int data)
{
	DEBUG_LOG("start head = %p, data = %d", head, data);
	if(!head) {
		ERROR_LOG("head = NULL");
		return -1;
	}
	struct list_node *new_node = create_node(data);
	new_node->data = data;
	new_node->next = head->next;
	head->next = new_node;
	DEBUG_LOG("end 0");
	return 0;
}

int insert_tail(struct list_node *head, int data)
{
	DEBUG_LOG("start head = %p, data = %d", head, data);
	if(!head) {
		ERROR_LOG("head = NULL");
		return -1;
	}
	struct list_node *new_node = create_node(data);
	new_node->data = data;
	struct list_node *node = head->next;
	if(!node) {
		return insert_head(head, data);
	}
	while(node) {
		if(!node->next) {
			node->next = new_node;
			break;
		}
		node = node->next;
	}
	DEBUG_LOG("end 0");
	return 0;
}

int insert_node(struct list_node *head, int point, int data)
{
	DEBUG_LOG("start head = %p, point = %d, data = %d", head, point, data);
	if(!head) {
		ERROR_LOG("head = NULL");
		return -1;
	}
	if(point > get_list_length(head) || point <= 0) {
		ERROR_LOG("invalid point:%d list length:%d", point, get_list_length(head));
		return -1;
	}
	struct list_node *new_node = create_node(data);
	new_node->data = data;
	struct list_node *node = head->next;
	if(1 == point) {
		return insert_head(head, data);
	}
	point--;
	while(point--) {
		node = node->next;
	}
	new_node->next = node->next;
	node->next = new_node;
	DEBUG_LOG("end 0");
	return 0;	
}

int delete_node(struct list_node *head, int point)
{
	DEBUG_LOG("start head = %p, point = %d", head, point);
	if(!head) {
		ERROR_LOG("head = NULL");
		return -1;
	}
	if(point > get_list_length(head) || point <= 0) {
		ERROR_LOG("invalid point:%d list length:%d", point, get_list_length(head));
		return -1;
	}
	struct list_node *node = head->next;
	if(1 == point) {
		head->next = node->next;
		free(node);
		return 0;
	}
	point -= 2;
	while(point--) {
		node = node->next;
	}
	struct list_node *delete_node = node->next;
	node->next = node->next->next;
	free(delete_node);
	DEBUG_LOG("end 0");
	return 0;
}

int print_list(struct list_node *head) 
{
	DEBUG_LOG("start head = %p", head);
	if(!head) {
		ERROR_LOG("head = NULL");
		return -1;
	}
	struct list_node *node = head->next;
	printf("list length:%d data:\n", get_list_length(head));
	while(node) {
		printf("%d--->", node->data);
		node = node->next;
	}
	printf("NULL\n");
	DEBUG_LOG("end 0");
	return 0;
}

int main()
{	
	struct list_node *head = create_list();
	insert_head(head, 1);
	insert_head(head, 2);
	insert_head(head, 3);
	insert_head(head, 4);
	insert_head(head, 5);
	insert_node(head, 3, 7);
	print_list(head);
/*	insert_node(NULL, 2, 5);
	insert_node(NULL, 20, 5);
	insert_head(NULL, 3);
	insert_tail(NULL, 4);
	delete_node(head, 1);
	delete_node(head, 10);
*/	print_list(head);
//	print_list(NULL);
	return 0;
}
